//! 赋值等一系列操作

use crate::parser::program::Program;
use crate::{
    parser::node::{self, Node},
    parser::{
        block_statement, expression, expression_statement, identifier, letstatement, program,
        return_statement,
    },
    Error as CreateError, Result,
};

use crate::lexer::token::Token;
use crate::parser::expression::Expression;
use std::collections::HashMap;
use std::fmt::{Debug, Formatter};

pub const INTEGER_OBJ: &str = "INTEGER";
pub const BOOLEAN_OBJ: &str = "BOOLEAN";
pub const NULL_OBJ: &str = "NULL";
pub const ERROR_OBJ: &str = "ERROR";
pub const RETURN_VALUE_OBJ: &str = "RETURN_VALUE";
pub const FUNCTION_LITERAL_OBJ: &str = "FUNCTION_LITERAL";
pub const FUNCTION_CALL_OBJ: &str = "FUNCTION_CALL";
pub const STRING_OBJ: &str = "STRING";
pub const ARRAY_OBJ: &str = "ARRAY";
pub const HASH_OBJ: &str = "HASH";

pub trait BaseObj {
    fn r#type(&self) -> &'static str;
    fn inspect(&self) -> String;
}

pub fn obj_to_type<T: BaseObj + Sized>(obj: &dyn BaseObj) -> &T {
    unsafe {
        use std::mem::transmute;
        let ptr = transmute::<&dyn BaseObj, (*const T, *const ())>(obj);
        &*ptr.0
    }
}

pub fn obj_to_type_own<T: BaseObj + Sized>(obj: Box<dyn BaseObj>) -> Box<T> {
    unsafe {
        use std::mem::transmute;
        let source = transmute::<Box<dyn BaseObj>, (*mut T, *const T)>(obj);
        Box::from_raw(source.0)
    }
}

impl Clone for Box<dyn BaseObj> {
    fn clone(&self) -> Self {
        match self.r#type() {
            INTEGER_OBJ => {
                let to_type = obj_to_type::<Integer>(self.as_ref());
                Box::new(to_type.clone())
            }
            BOOLEAN_OBJ => {
                let to_type = obj_to_type::<Boolean>(self.as_ref());
                Box::new(to_type.clone())
            }
            NULL_OBJ => {
                let to_type = obj_to_type::<NULL>(self.as_ref());
                Box::new(to_type.clone())
            }
            ERROR_OBJ => {
                let to_type = obj_to_type::<Error>(self.as_ref());
                Box::new(to_type.clone())
            }
            RETURN_VALUE_OBJ => {
                let to_type = obj_to_type::<ReturnValue>(self.as_ref());
                Box::new(to_type.clone())
            }
            FUNCTION_LITERAL_OBJ => {
                let to_type = obj_to_type::<FunctionLiteral>(self.as_ref());
                Box::new(to_type.clone())
            }

            FUNCTION_CALL_OBJ => {
                let to_type = obj_to_type::<FunctionCall>(self.as_ref());
                Box::new(to_type.clone())
            }
            STRING_OBJ => {
                let to_type = obj_to_type::<StringLiteral>(self.as_ref());
                Box::new(to_type.clone())
            }
            ARRAY_OBJ => {
                let to_type = obj_to_type::<Array>(self.as_ref());
                Box::new(to_type.clone())
            }
            HASH_OBJ => {
                let to_type = obj_to_type::<Hash>(self.as_ref());
                Box::new(to_type.clone())
            }
            t => panic!("不支持的类型:{}", t),
        }
    }
}

impl Debug for &dyn BaseObj {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self.r#type() {
            INTEGER_OBJ => {
                let to_type = obj_to_type::<Integer>(*self);
                to_type.fmt(f)
            }
            BOOLEAN_OBJ => {
                let to_type = obj_to_type::<Boolean>(*self);
                to_type.fmt(f)
            }
            NULL_OBJ => {
                let to_type = obj_to_type::<NULL>(*self);
                to_type.fmt(f)
            }
            ERROR_OBJ => {
                let to_type = obj_to_type::<Error>(*self);
                to_type.fmt(f)
            }
            RETURN_VALUE_OBJ => {
                let to_type = obj_to_type::<ReturnValue>(*self);
                to_type.fmt(f)
            }
            FUNCTION_LITERAL_OBJ => {
                let to_type = obj_to_type::<FunctionLiteral>(*self);
                to_type.fmt(f)
            }
            FUNCTION_CALL_OBJ => {
                let to_type = obj_to_type::<FunctionCall>(*self);
                to_type.fmt(f)
            }
            STRING_OBJ => {
                let to_type = obj_to_type::<StringLiteral>(*self);
                to_type.fmt(f)
            }
            ARRAY_OBJ => {
                let to_type = obj_to_type::<Array>(*self);
                to_type.fmt(f)
            }
            HASH_OBJ => {
                let to_type = obj_to_type::<Hash>(*self);
                to_type.fmt(f)
            }
            t => panic!("不支持的类型:{}", t),
        }
    }
}

impl Debug for Box<dyn BaseObj> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let ret = self.as_ref();
        <&dyn BaseObj as Debug>::fmt(&ret, f)
    }
}

//------------整型-------------------------------
#[derive(Debug, Clone)]
pub struct Integer {
    value: f64,
}

impl Integer {
    pub fn new(value: f64) -> Self {
        Self { value }
    }
}

/// 整型
impl BaseObj for Integer {
    fn r#type(&self) -> &'static str {
        INTEGER_OBJ
    }

    fn inspect(&self) -> String {
        format!("(integer){}", self.value)
    }
}

//------------布尔型-------------------------------
#[derive(Debug, Clone)]
pub struct Boolean {
    value: bool,
}
impl Boolean {
    pub fn new(value: bool) -> Self {
        Self { value }
    }
}
impl BaseObj for Boolean {
    fn r#type(&self) -> &'static str {
        BOOLEAN_OBJ
    }

    fn inspect(&self) -> String {
        format!("(boolean){}", self.value)
    }
}

//------------NULL-------------------------------
#[derive(Debug, Clone)]
pub struct NULL;
impl BaseObj for NULL {
    fn r#type(&self) -> &'static str {
        NULL_OBJ
    }

    fn inspect(&self) -> String {
        "null".to_string()
    }
}

//------------错误类型-------------------------------
#[derive(Debug, Clone)]
pub struct Error {
    msg: String,
}
impl Error {
    #[allow(unused)]
    pub fn new(msg: &str) -> Self {
        Self {
            msg: msg.to_string(),
        }
    }
}
impl BaseObj for Error {
    fn r#type(&self) -> &'static str {
        ERROR_OBJ
    }

    fn inspect(&self) -> String {
        self.msg.clone()
    }
}

//------------返回值类型-------------------------------
#[derive(Debug, Clone)]
pub struct ReturnValue {
    value_obj: Box<dyn BaseObj>,
}

impl ReturnValue {
    pub fn new(value: Box<dyn BaseObj>) -> Self {
        Self { value_obj: value }
    }
}

impl BaseObj for ReturnValue {
    fn r#type(&self) -> &'static str {
        RETURN_VALUE_OBJ
    }

    fn inspect(&self) -> String {
        format!("(return){}", self.value_obj.inspect())
    }
}

//------------函数类型-------------------------------
#[derive(Debug, Clone)]
pub struct FunctionLiteral {
    token: Token,
    parameters: Vec<identifier::Identifier>,
    block_statement: block_statement::BlockStatement,
}

impl FunctionLiteral {
    pub fn new(
        token: Token,
        parameters: Vec<identifier::Identifier>,
        block_statement: block_statement::BlockStatement,
    ) -> Self {
        Self {
            token,
            parameters,
            block_statement,
        }
    }
}

impl BaseObj for FunctionLiteral {
    fn r#type(&self) -> &'static str {
        FUNCTION_LITERAL_OBJ
    }

    fn inspect(&self) -> String {
        let mut s = String::from("fn(");
        for p in &self.parameters {
            s.push_str(&p.get_literal());
            s.push(',');
        }
        if self.parameters.len() > 0 {
            let _ = s.pop();
        }
        s.push_str("){\n");
        s.push_str(self.block_statement.get_literal());
        s.push_str("\n}");
        s
    }
}

//------------函数调用类型-------------------------------
#[derive(Debug, Clone)]
pub struct FunctionCall {
    identifiers: Vec<identifier::Identifier>,
    block_statement: block_statement::BlockStatement,
    environment: Environment,
}

impl FunctionCall {
    pub fn new(
        identifiers: Vec<identifier::Identifier>,
        block_statement: block_statement::BlockStatement,
    ) -> Self {
        Self {
            identifiers,
            block_statement,
            environment: Environment::new(),
        }
    }
}

impl BaseObj for FunctionCall {
    fn r#type(&self) -> &'static str {
        FUNCTION_CALL_OBJ
    }

    fn inspect(&self) -> String {
        let mut ret = String::from("(");
        for i in &self.identifiers {
            ret.push_str(i.get_literal());
            ret.push(',');
        }
        if self.identifiers.len() > 0 {
            let _ = ret.pop();
        }
        ret.push_str(")");
        ret
    }
}

//------------字符串类型-------------------------------
#[derive(Debug, Clone)]
pub struct StringLiteral {
    value: String,
}

impl StringLiteral {
    pub fn new(value: &str) -> Self {
        Self {
            value: value.to_string(),
        }
    }

    pub fn value(&self) -> &str {
        &self.value
    }
}

impl BaseObj for StringLiteral {
    fn r#type(&self) -> &'static str {
        STRING_OBJ
    }

    fn inspect(&self) -> String {
        format!("(string){}", self.value)
    }
}

//------------数组类型-------------------------------
#[derive(Debug, Clone)]
pub struct Array {
    elements: Vec<Box<dyn BaseObj>>,
}

impl Array {
    pub fn new(elements: Vec<Box<dyn BaseObj>>) -> Self {
        Self { elements }
    }

    pub fn elements(&self) -> &[Box<dyn BaseObj>] {
        &self.elements
    }
}

impl BaseObj for Array {
    fn r#type(&self) -> &'static str {
        ARRAY_OBJ
    }

    fn inspect(&self) -> String {
        let mut ret = String::from("(array)");
        for e in &self.elements {
            ret.push_str(&e.inspect());
            ret.push(',');
        }
        if self.elements.len() > 0 {
            let _ = ret.pop();
        }
        ret
    }
}

//------------哈希类型-------------------------------
#[derive(Debug, Clone)]
pub struct Hash {
    keys: Vec<Box<dyn BaseObj>>,
    values: Vec<Box<dyn BaseObj>>,
}

impl Hash {
    pub fn new(keys: Vec<Box<dyn BaseObj>>, values: Vec<Box<dyn BaseObj>>) -> Self {
        Self { keys, values }
    }

    pub fn keys(&self) -> &Vec<Box<dyn BaseObj>> {
        &self.keys
    }

    pub fn values(&self) -> &Vec<Box<dyn BaseObj>> {
        &self.values
    }
}

impl BaseObj for Hash {
    fn r#type(&self) -> &'static str {
        HASH_OBJ
    }

    fn inspect(&self) -> String {
        let mut s = String::from("(hash){");
        for (index, key) in self.keys.iter().enumerate() {
            s.push_str(&key.inspect());
            s.push(':');
            let value = if self.values.get(index).is_none() {
                Box::new(NULL)
            } else {
                self.values.get(index).unwrap().clone()
            };
            s.push_str(&value.inspect());
            s.push(',');
        }
        if self.keys.len() > 0 {
            let _ = s.pop();
        }
        s
    }
}

/// 哈希保存是可能是数值，布尔型等等.
#[derive(Debug, Clone)]
pub struct Environment {
    map: HashMap<String, Box<dyn BaseObj>>,
    outer: Option<Box<Environment>>,
}

impl Environment {
    pub fn new() -> Self {
        Self {
            map: HashMap::default(),
            outer: None,
        }
    }

    pub fn get(&self, name: &str) -> Option<&Box<dyn BaseObj>> {
        let obj = self.map.get(name);
        if let Some(o) = obj {
            return Some(o);
        }
        if let Some(outer) = &self.outer {
            return outer.get(name);
        }
        None
    }

    pub fn set(&mut self, name: &str, obj: Box<dyn BaseObj>) {
        self.map.insert(name.to_string(), obj);
    }
}

#[derive(Debug, Clone)]
pub struct Evaluator {
    environment: Environment,
}

impl Evaluator {
    pub fn new() -> Self {
        Self {
            environment: Environment::new(),
        }
    }
    /// eval会返回null类型，比如空的block语句等
    #[allow(unused)]
    pub fn eval(&mut self, node: &dyn Node) -> Box<dyn BaseObj> {
        match node.get_type().as_ref() {
            "Program" => {
                let program = node::cast_down_type::<program::Program>(node);
                self.eval_program(program)
            }
            "LetStatement" => {
                let let_stmt = node::cast_down_type::<letstatement::LetStatement>(node);
                let val = self.eval(let_stmt.value().cast_to_node());
                if Self::is_error(val.as_ref()) {
                    return val;
                }
                self.environment
                    .set(let_stmt.name().get_literal(), val.clone());
                val
            }
            "Identifier" => {
                let identifier = node::cast_down_type::<identifier::Identifier>(node);
                let value = self.eval_identifier(identifier);
                value
            }
            "Integer" => {
                let integer = node::cast_down_type::<expression::Integer>(node);
                let value = integer.value();
                Box::new(Integer::new(value))
            }
            "Null" => Box::new(NULL),
            "Boolean" => {
                let boolean = node::cast_down_type::<expression::Boolean>(node);
                let value = boolean.value();
                Box::new(Boolean::new(value))
            }
            "StringLiteral" => {
                let str = node::cast_down_type::<expression::StringLiteral>(node);
                Box::new(StringLiteral::new(str.get_literal()))
            }
            "HashLiteral" => {
                let hash_literal = node::cast_down_type::<expression::HashLiteral>(node);
                self.eval_hash_literal(hash_literal)
            }
            "ExpressionStatement" => {
                let expression_statement =
                    node::cast_down_type::<expression_statement::ExpressionStatement>(node);
                self.eval(expression_statement.expression().cast_to_node())
            }
            "PrefixExpression" => {
                let pre_exp = node::cast_down_type::<expression::PrefixExpression>(node);
                let right = self.eval(pre_exp.right().cast_to_node());
                if Self::is_error(right.as_ref()) {
                    return right;
                }
                Self::eval_prefix_expression(pre_exp.operator(), right.as_ref())
            }
            "InfixExpression" => {
                let infix_exp = node::cast_down_type::<expression::InfixExpression>(node);
                let left = self.eval(infix_exp.left().cast_to_node());
                let right = self.eval(infix_exp.right().cast_to_node());
                Self::eval_infix_expression(infix_exp.operator(), left.as_ref(), right.as_ref())
            }

            "IfExpression" => {
                let if_expression = node::cast_down_type::<expression::IfExpression>(node);
                self.eval_if_expression(if_expression)
            }

            "BlockStatement" => {
                let block_stmt = node::cast_down_type::<block_statement::BlockStatement>(node);
                self.eval_block_stmt(block_stmt)
            }
            "ReturnStatement" => {
                let return_stmts = node::cast_down_type::<return_statement::ReturnStatement>(node);
                let value = self.eval(return_stmts.expression().cast_to_node());
                if Self::is_error(value.as_ref()) {
                    return value;
                }
                let return_value = ReturnValue::new(value);
                Box::new(return_value)
            }
            "FunctionLiteral" => {
                let func = node::cast_down_type::<expression::FunctionLiteral>(node);
                let identifiers = func.parameters().clone();
                let block_stmt = func.body().clone();
                let mut ret = Box::new(FunctionCall::new(identifiers, block_stmt));
                ret.environment = Self::new_enclosed_environment(&self.environment);
                ret
            }
            "CallExpression" => {
                let call = node::cast_down_type::<expression::CallExpression>(node);
                let args = self.eval_expressions(call.arguments());
                if let Err(args) = args {
                    return Box::new(Error::new(&args.to_string()));
                }
                let args = args.unwrap();
                let function_call = self.eval(call.function().cast_to_node());
                if Self::is_error(function_call.as_ref()) {
                    return Self::builtins(call.function().cast_to_node().get_literal(), &args[..]);
                }
                let mut function_call = obj_to_type_own::<FunctionCall>(function_call);

                // for a in &args {
                //     println!("{}", a.inspect());
                // }
                // 执行函数前保留当前的绑定环境
                let old_environment = self.environment.clone();
                // 设置新的绑定环境
                self.environment = function_call.environment.clone();
                // 讲输入参数名称与传入值进行绑定
                if args.len() != function_call.identifiers.len() {
                    return Box::new(Error::new("函数调用参数不一致"));
                }
                for (pos, ident) in function_call.identifiers.iter().enumerate() {
                    let name = ident.get_literal();
                    let val = args[pos].clone();
                    self.environment.set(name, val);
                }

                // 执行函数体内的代码
                let result = self.eval(function_call.block_statement.cast_to_node());
                // 恢复原来的环境变量
                self.environment = old_environment;

                if result.r#type() == RETURN_VALUE_OBJ {
                    let ret = obj_to_type_own::<ReturnValue>(result);
                    return ret.value_obj;
                }
                return result;
            }
            "EqualSign" => {
                let equal_sign = node::cast_down_type::<expression::EqualSign>(node);
                let left_ident = equal_sign.left().get_literal();
                let right = self.eval(equal_sign.right().cast_to_node());
                if self.environment.get(left_ident).is_none() {
                    return Box::new(Error::new(&format!("变量:{}未定义", left_ident)));
                }
                self.environment.set(left_ident, right.clone());
                right
            }
            "ArrayLiteral" => {
                let array = node::cast_down_type::<expression::ArrayLiteral>(node);
                let elements = self.eval_expressions(array.elements());
                if let Err(args) = elements {
                    return Box::new(Error::new(&args.to_string()));
                }
                Box::new(Array::new(elements.unwrap()))
            }
            "IndexExpression" => {
                let index_expression = node::cast_down_type::<expression::IndexExpression>(node);
                let left = self.eval(index_expression.left().cast_to_node());
                if Self::is_error(left.as_ref()) {
                    return left;
                }
                let index = self.eval(index_expression.index().cast_to_node());
                if Self::is_error(index.as_ref()) {
                    return index;
                }
                let obj = self.eval_index_expression(left.as_ref(), index.as_ref());
                obj
            }
            t => Box::new(Error::new(&format!("不支持的节点类型:{}", t))),
        }
    }

    fn eval_prefix_expression(operator: &str, right: &dyn BaseObj) -> Box<dyn BaseObj> {
        match operator {
            "!" => Box::new(Self::eval_bang_operator_expression(right)),
            "-" => Box::new(Self::eval_minus_operator_expression(right)),
            o => panic!("不支持的操作符号:{}", o),
        }
    }

    fn eval_bang_operator_expression(right: &dyn BaseObj) -> Boolean {
        let mut value = false;
        match right.r#type() {
            BOOLEAN_OBJ => {
                let boolean = obj_to_type::<Boolean>(right);
                if boolean.value {
                    value = false;
                } else {
                    value = true;
                }
            }
            INTEGER_OBJ => {
                let integer = obj_to_type::<Integer>(right);
                if integer.value == 0.0 {
                    value = true;
                } else {
                    value = false;
                }
            }
            NULL_OBJ => value = true,
            t => panic!("不支持的类型:{}", t),
        }

        Boolean::new(value)
    }

    fn eval_minus_operator_expression(right: &dyn BaseObj) -> Integer {
        if right.r#type() != INTEGER_OBJ {
            panic!("unknown operator:-{}", right.inspect());
        }
        let mut integer = obj_to_type::<Integer>(right).clone();
        integer.value = -integer.value;
        integer
    }

    fn eval_infix_expression(
        operator: &str,
        left: &dyn BaseObj,
        right: &dyn BaseObj,
    ) -> Box<dyn BaseObj> {
        if left.r#type() != right.r#type() {
            return Box::new(Error::new(&format!(
                "type mismatched: {} and {}",
                left.r#type(),
                right.r#type()
            )));
        }
        if left.r#type() == INTEGER_OBJ && right.r#type() == INTEGER_OBJ {
            return Self::eval_integer_infix_expression(
                operator,
                obj_to_type::<Integer>(left),
                obj_to_type::<Integer>(right),
            );
        }

        if left.r#type() == BOOLEAN_OBJ && right.r#type() == BOOLEAN_OBJ {
            return Box::new(Self::eval_boolean_infix_expression(
                operator,
                obj_to_type::<Boolean>(left),
                obj_to_type::<Boolean>(right),
            ));
        }

        if left.r#type() == STRING_OBJ && right.r#type() == STRING_OBJ {
            return Box::new(Self::eval_string_infix_expression(
                operator,
                obj_to_type::<StringLiteral>(left),
                obj_to_type::<StringLiteral>(right),
            ));
        }

        return if left.r#type() == NULL_OBJ && right.r#type() == NULL_OBJ {
            Box::new(Boolean::new(true))
        } else {
            Box::new(Boolean::new(false))
        };

        panic!("中序表达式不支持的类型:{}", left.r#type());
    }

    fn eval_integer_infix_expression(
        operator: &str,
        left: &Integer,
        right: &Integer,
    ) -> Box<dyn BaseObj> {
        let left_val = left.value;
        let right_val = right.value;
        let mut result_type = "integer";
        let mut result_bool = false;
        let mut result_value = 0.0;
        match operator {
            "+" => {
                result_value = left_val + right_val;
            }
            "-" => {
                result_value = left_val - right_val;
            }
            "*" => {
                result_value = left_val * right_val;
            }
            "/" => {
                result_value = left_val / right_val;
            }
            "==" => {
                result_type = "boolean";
                result_bool = left_val == right_val;
            }
            "!=" => {
                result_type = "boolean";
                result_bool = left_val != right_val;
            }
            ">" => {
                result_type = "boolean";
                result_bool = left_val > right_val;
            }
            "<" => {
                result_type = "boolean";
                result_bool = left_val < right_val;
            }
            o => panic!("不支持的运算符:{}", o),
        }
        if result_type == "integer" {
            Box::new(Integer::new(result_value))
        } else {
            Box::new(Boolean::new(result_bool))
        }
    }

    fn eval_boolean_infix_expression(operator: &str, left: &Boolean, right: &Boolean) -> Boolean {
        let value = match operator {
            "==" => left.value == right.value,
            "!=" => left.value != right.value,
            o => panic!("不支持的运算符:{}", o),
        };
        Boolean::new(value)
    }

    fn eval_string_infix_expression(
        _operator: &str,
        left: &StringLiteral,
        right: &StringLiteral,
    ) -> StringLiteral {
        let left_value = left.value();
        let right_value = right.value();
        StringLiteral::new(&format!("{}{}", left_value, right_value))
    }

    fn eval_if_expression(&mut self, if_exp: &expression::IfExpression) -> Box<dyn BaseObj> {
        let condition = self.eval(if_exp.condition().cast_to_node());
        if Self::is_error(condition.as_ref()) {
            return condition;
        }
        if Self::is_truthy(condition.as_ref()) {
            self.eval(if_exp.consequence().cast_to_node())
        } else {
            if let Some(alter) = if_exp.alternative() {
                self.eval(alter.cast_to_node())
            } else {
                Box::new(NULL)
            }
        }
    }

    fn eval_block_stmt(&mut self, stmts: &block_statement::BlockStatement) -> Box<dyn BaseObj> {
        let mut result: Box<dyn BaseObj> = Box::new(NULL);
        for s in stmts.statements() {
            let tmp = self.eval(s.cast_to_node());
            if tmp.r#type() == RETURN_VALUE_OBJ || tmp.r#type() == ERROR_OBJ {
                return tmp;
            }

            result = tmp;
        }
        result
    }

    fn eval_program(&mut self, program: &Program) -> Box<dyn BaseObj> {
        let mut result: Box<dyn BaseObj> = Box::new(NULL);
        for p in program.statements() {
            result = self.eval(p.cast_to_node());
            if result.r#type() == RETURN_VALUE_OBJ {
                let result = obj_to_type_own::<ReturnValue>(result);
                return result.value_obj;
            }
            // if result.r#type() == NULL_OBJ {
            //     return result;
            // }

            if result.r#type() == ERROR_OBJ {
                let r = obj_to_type::<Error>(result.as_ref());
                println!("{}", r.msg);
                return result;
            }
        }

        result
    }

    fn eval_identifier(&mut self, identifier: &identifier::Identifier) -> Box<dyn BaseObj> {
        let val = self.environment.get(identifier.get_literal());
        if let Some(val) = val {
            return val.clone();
        }
        Box::new(Error::new(&format!(
            "标识符没有找到:{}",
            identifier.get_literal()
        )))
    }

    fn eval_expressions(
        &mut self,
        exp: &Vec<Box<dyn Expression>>,
    ) -> Result<Vec<Box<dyn BaseObj>>> {
        let mut result = vec![];
        for e in exp {
            let evaluated = self.eval(e.as_ref().cast_to_node());
            if Self::is_error(evaluated.as_ref()) {
                return Err(CreateError::from(evaluated.inspect()));
            }
            result.push(evaluated);
        }
        Ok(result)
    }

    fn eval_index_expression(
        &mut self,
        left: &dyn BaseObj,
        index: &dyn BaseObj,
    ) -> Box<dyn BaseObj> {
        if left.r#type() == ARRAY_OBJ && index.r#type() == INTEGER_OBJ {
            let array = obj_to_type::<Array>(left);
            let index = obj_to_type::<Integer>(index);
            return self.eval_array_index_expression(array, index);
        }
        if left.r#type() == HASH_OBJ {
            let hash = obj_to_type::<Hash>(left);
            return self.eval_hash_index_expression(hash, index);
        }
        panic!("不支持类型索引");
    }

    fn eval_array_index_expression(&mut self, array: &Array, index: &Integer) -> Box<dyn BaseObj> {
        let i = index.value as usize;
        let max = array.elements.len() - 1;
        if i < 0 || i > max {
            return Box::new(NULL);
        }
        array.elements()[i].clone()
    }

    fn eval_hash_index_expression(&mut self, hash: &Hash, index: &dyn BaseObj) -> Box<dyn BaseObj> {
        if !Self::hashtable(index) {
            return Box::new(Error::new(&format!("不支持的键值类型:{}", index.r#type())));
        }
        for (i, key) in hash.keys().iter().enumerate() {
            let ret = match index.r#type() {
                INTEGER_OBJ => {
                    let index = obj_to_type::<Integer>(index);
                    let key = obj_to_type::<Integer>(key.as_ref());
                    key.value == index.value
                }
                STRING_OBJ => {
                    let index = obj_to_type::<StringLiteral>(index);
                    let key = obj_to_type::<StringLiteral>(key.as_ref());
                    key.value() == index.value()
                }
                BOOLEAN_OBJ => {
                    let index = obj_to_type::<Boolean>(index);
                    let key = obj_to_type::<Boolean>(key.as_ref());
                    key.value == index.value
                }
                t => panic!("不支持的键值类型:{}", t),
            };
            if ret {
                return hash.values()[i].clone();
            }
        }
        Box::new(NULL)
    }

    fn eval_hash_literal(&mut self, hash_literal: &expression::HashLiteral) -> Box<dyn BaseObj> {
        let mut keys: Vec<Box<dyn BaseObj>> = vec![];
        let mut values: Vec<Box<dyn BaseObj>> = vec![];
        for (index, k) in hash_literal.keys().iter().enumerate() {
            let key = self.eval(k.cast_to_node());
            if Self::is_error(key.as_ref()) {
                return key;
            }
            if !Self::hashtable(key.as_ref()) {
                return Box::new(Error::new(&format!(
                    "键值不支持的哈希类型:{}",
                    key.r#type()
                )));
            }
            let value = self.eval(hash_literal.values().get(index).unwrap().cast_to_node());
            if Self::is_error(value.as_ref()) {
                return value;
            }
            keys.push(key);
            values.push(value);
        }
        Box::new(Hash::new(keys, values))
    }

    fn hashtable(node: &dyn BaseObj) -> bool {
        if node.r#type() == INTEGER_OBJ
            || node.r#type() == STRING_OBJ
            || node.r#type() == BOOLEAN_OBJ
        {
            return true;
        }
        false
    }
    fn is_truthy(con: &dyn BaseObj) -> bool {
        match con.r#type() {
            INTEGER_OBJ => {
                let integer = obj_to_type::<Integer>(con);
                if integer.value != 0.0 {
                    true
                } else {
                    false
                }
            }
            BOOLEAN_OBJ => {
                let boolean = obj_to_type::<Boolean>(con);
                boolean.value
            }
            NULL_OBJ => false,
            _ => true,
        }
    }

    pub fn is_error(obj: &dyn BaseObj) -> bool {
        obj.r#type() == ERROR_OBJ
    }

    fn new_enclosed_environment(old: &Environment) -> Environment {
        let mut environment = Environment::new();
        environment.outer = Some(Box::new(old.clone()));
        environment
    }

    fn builtins(name: &str, args: &[Box<dyn BaseObj>]) -> Box<dyn BaseObj> {
        match name {
            "__len" => Self::len(args),
            "__println" => Self::println(args),
            "__first" => Self::array_first(args),
            "__rest" => Self::array_rest(args),
            func => Box::new(Error::new(&format!("不支持的内嵌函数: {}", func))),
        }
    }

    fn len(args: &[Box<dyn BaseObj>]) -> Box<dyn BaseObj> {
        if args.len() != 1 {
            return Box::new(Error::new("错误的参数数量"));
        }

        match args[0].r#type() {
            STRING_OBJ => {
                let string_obj = obj_to_type::<StringLiteral>(args[0].as_ref());
                let value = string_obj.value().len();
                let obj = Integer::new(value as f64);
                Box::new(obj)
            }
            ARRAY_OBJ => {
                let array_obj = obj_to_type::<Array>(args[0].as_ref());
                let value = array_obj.elements.len();
                Box::new(Integer::new(value as f64))
            }
            a => Box::new(Error::new(&format!("不支持参数类型: {}", a))),
        }
    }

    fn println(args: &[Box<dyn BaseObj>]) -> Box<dyn BaseObj> {
        let mut str = String::default();
        for a in args {
            match a.r#type() {
                INTEGER_OBJ => {
                    let integer = obj_to_type::<Integer>(a.as_ref());
                    str.push_str(&integer.value.to_string());
                }
                STRING_OBJ => {
                    let sl = obj_to_type::<StringLiteral>(a.as_ref());
                    str.push_str(sl.value());
                }
                BOOLEAN_OBJ => {
                    let boolean = obj_to_type::<Boolean>(a.as_ref());
                    if boolean.value {
                        str.push_str("true");
                    } else {
                        str.push_str("false");
                    }
                }
                NULL_OBJ => str.push_str("null"),
                ERROR_OBJ => {
                    let error = obj_to_type::<Error>(a.as_ref());
                    str.push_str(&error.msg);
                }
                RETURN_VALUE_OBJ => {
                    let return_value = obj_to_type::<ReturnValue>(a.as_ref());
                    str.push_str(&&return_value.inspect());
                }
                FUNCTION_LITERAL_OBJ => {
                    let function_literal = obj_to_type::<FunctionLiteral>(a.as_ref());
                    str.push_str(&function_literal.inspect());
                }
                FUNCTION_CALL_OBJ => {
                    let func_call = obj_to_type::<FunctionCall>(a.as_ref());
                    str.push_str(&func_call.inspect());
                }
                ARRAY_OBJ => {
                    let array = obj_to_type::<Array>(a.as_ref());
                    str.push_str(&array.inspect());
                }
                HASH_OBJ => {
                    let hash = obj_to_type::<Hash>(a.as_ref());
                    str.push_str(&hash.inspect());
                }
                t => panic!("__println函数不支持的类型: {}", t),
            }
        }
        println!("{}", str);
        Box::new(NULL)
    }

    fn array_first(args: &[Box<dyn BaseObj>]) -> Box<dyn BaseObj> {
        if args.len() != 1 {
            return Box::new(Error::new("参数的数量错误"));
        }
        if args[0].r#type() != ARRAY_OBJ {
            return Box::new(Error::new("参数的类型必须是数组类型"));
        }
        let array = obj_to_type::<Array>(args[0].as_ref());
        if array.elements().len() > 0 {
            return array.elements()[0].clone();
        }
        return Box::new(NULL);
    }

    fn array_rest(args: &[Box<dyn BaseObj>]) -> Box<dyn BaseObj> {
        if args.len() != 1 {
            return Box::new(Error::new("参数必须是一个"));
        }

        if args[0].r#type() != ARRAY_OBJ {
            return Box::new(Error::new("参数类型必须是数组"));
        }
        let array = obj_to_type::<Array>(args[0].as_ref());
        if array.elements().len() > 1 {
            let new = &array.elements()[1..];
            return Box::new(Array::new(new.to_vec()));
        }
        return Box::new(NULL);
    }
}
